import 'dart:typed_data';

import 'package:dartssh2/src/kex/kex_dh.dart';
import 'package:dartssh2/src/utils/bigint.dart';
import 'package:test/test.dart';

void main() {
  group('SSHKexDH', () {
    test('SSHKexDH.group1', () {
      final kex1 = SSHKexDH.group1();
      final kex2 = SSHKexDH.group1();
      final secret1 = kex1.computeSecret(kex2.e);
      final secret2 = kex2.computeSecret(kex1.e);
      expect(secret1, secret2);
    });

    test('SSHKexDH.group14', () {
      final kex1 = SSHKexDH.group14();
      final kex2 = SSHKexDH.group14();
      final secret1 = kex1.computeSecret(kex2.e);
      final secret2 = kex2.computeSecret(kex1.e);
      expect(secret1, secret2);
    });
    test('should initialize with valid parameters (Group 1)', () {
      final kex = SSHKexDH.group1();
      expect(kex.p, equals(_group1Prime));
      expect(kex.g, equals(BigInt.from(2)));
      expect(kex.secretBits, equals(160));
      expect(kex.x, isNotNull);
      expect(kex.e, isNotNull);
    });

    test('should initialize with valid parameters (Group 14)', () {
      final kex = SSHKexDH.group14();
      expect(kex.p, equals(_group14Prime));
      expect(kex.g, equals(BigInt.from(2)));
      expect(kex.secretBits, equals(224));
      expect(kex.x, isNotNull);
      expect(kex.e, isNotNull);
    });

    test('should throw ArgumentError for invalid secretBits', () {
      expect(
        () => SSHKexDH(p: _group1Prime, g: BigInt.from(2), secretBits: 159),
        throwsA(isA<ArgumentError>()),
      );
    });

    test('should compute shared secret correctly', () {
      final kex = SSHKexDH.group14();

      // Example public key f, manually set to a valid value for testing.
      // This should be a known good value for testing purposes.
      final f = BigInt.from(
          1234567890123456789); // Replace with a known valid value if possible

      final computedSecret = kex.computeSecret(f);
      expect(computedSecret, equals(isA<BigInt>()));
    });
  });
}

// Predefined group 1 prime
final _group1Prime = decodeBigIntWithSign(
  1,
  Uint8List.fromList([
    0xff,
    0xff,
    0xff,
    0xff,
    0xff,
    0xff,
    0xff,
    0xff,
    0xc9,
    0x0f,
    0xda,
    0xa2,
    0x21,
    0x68,
    0xc2,
    0x34,
    0xc4,
    0xc6,
    0x62,
    0x8b,
    0x80,
    0xdc,
    0x1c,
    0xd1,
    0x29,
    0x02,
    0x4e,
    0x08,
    0x8a,
    0x67,
    0xcc,
    0x74,
    0x02,
    0x0b,
    0xbe,
    0xa6,
    0x3b,
    0x13,
    0x9b,
    0x22,
    0x51,
    0x4a,
    0x08,
    0x79,
    0x8e,
    0x34,
    0x04,
    0xdd,
    0xef,
    0x95,
    0x19,
    0xb3,
    0xcd,
    0x3a,
    0x43,
    0x1b,
    0x30,
    0x2b,
    0x0a,
    0x6d,
    0xf2,
    0x5f,
    0x14,
    0x37,
    0x4f,
    0xe1,
    0x35,
    0x6d,
    0x6d,
    0x51,
    0xc2,
    0x45,
    0xe4,
    0x85,
    0xb5,
    0x76,
    0x62,
    0x5e,
    0x7e,
    0xc6,
    0xf4,
    0x4c,
    0x42,
    0xe9,
    0xa6,
    0x37,
    0xed,
    0x6b,
    0x0b,
    0xff,
    0x5c,
    0xb6,
    0xf4,
    0x06,
    0xb7,
    0xed,
    0xee,
    0x38,
    0x6b,
    0xfb,
    0x5a,
    0x89,
    0x9f,
    0xa5,
    0xae,
    0x9f,
    0x24,
    0x11,
    0x7c,
    0x4b,
    0x1f,
    0xe6,
    0x49,
    0x28,
    0x66,
    0x51,
    0xec,
    0xe6,
    0x53,
    0x81,
    0xff,
    0xff,
    0xff,
    0xff,
    0xff,
    0xff,
    0xff,
    0xff,
  ]),
);

// Predefined group 14 prime
final _group14Prime = decodeBigIntWithSign(
  1,
  Uint8List.fromList([
    0xff,
    0xff,
    0xff,
    0xff,
    0xff,
    0xff,
    0xff,
    0xff,
    0xc9,
    0x0f,
    0xda,
    0xa2,
    0x21,
    0x68,
    0xc2,
    0x34,
    0xc4,
    0xc6,
    0x62,
    0x8b,
    0x80,
    0xdc,
    0x1c,
    0xd1,
    0x29,
    0x02,
    0x4e,
    0x08,
    0x8a,
    0x67,
    0xcc,
    0x74,
    0x02,
    0x0b,
    0xbe,
    0xa6,
    0x3b,
    0x13,
    0x9b,
    0x22,
    0x51,
    0x4a,
    0x08,
    0x79,
    0x8e,
    0x34,
    0x04,
    0xdd,
    0xef,
    0x95,
    0x19,
    0xb3,
    0xcd,
    0x3a,
    0x43,
    0x1b,
    0x30,
    0x2b,
    0x0a,
    0x6d,
    0xf2,
    0x5f,
    0x14,
    0x37,
    0x4f,
    0xe1,
    0x35,
    0x6d,
    0x6d,
    0x51,
    0xc2,
    0x45,
    0xe4,
    0x85,
    0xb5,
    0x76,
    0x62,
    0x5e,
    0x7e,
    0xc6,
    0xf4,
    0x4c,
    0x42,
    0xe9,
    0xa6,
    0x37,
    0xed,
    0x6b,
    0x0b,
    0xff,
    0x5c,
    0xb6,
    0xf4,
    0x06,
    0xb7,
    0xed,
    0xee,
    0x38,
    0x6b,
    0xfb,
    0x5a,
    0x89,
    0x9f,
    0xa5,
    0xae,
    0x9f,
    0x24,
    0x11,
    0x7c,
    0x4b,
    0x1f,
    0xe6,
    0x49,
    0x28,
    0x66,
    0x51,
    0xec,
    0xe4,
    0x5b,
    0x3d,
    0xc2,
    0x00,
    0x7c,
    0xb8,
    0xa1,
    0x63,
    0xbf,
    0x05,
    0x98,
    0xda,
    0x48,
    0x36,
    0x1c,
    0x55,
    0xd3,
    0x9a,
    0x69,
    0x16,
    0x3f,
    0xa8,
    0xfd,
    0x24,
    0xcf,
    0x5f,
    0x83,
    0x65,
    0x5d,
    0x23,
    0xdc,
    0xa3,
    0xad,
    0x96,
    0x1c,
    0x62,
    0xf3,
    0x56,
    0x20,
    0x85,
    0x52,
    0xbb,
    0x9e,
    0xd5,
    0x29,
    0x07,
    0x70,
    0x96,
    0x96,
    0x6d,
    0x67,
    0x0c,
    0x35,
    0x4e,
    0x4a,
    0xbc,
    0x98,
    0x04,
    0xf1,
    0x74,
    0x6c,
    0x08,
    0xca,
    0x18,
    0x21,
    0x7c,
    0x32,
    0x90,
    0x5e,
    0x46,
    0x2e,
    0x36,
    0xce,
    0x3b,
    0xe3,
    0x9e,
    0x77,
    0x2c,
    0x18,
    0x0e,
    0x86,
    0x03,
    0x9b,
    0x27,
    0x83,
    0xa2,
    0xec,
    0x07,
    0xa2,
    0x8f,
    0xb5,
    0xc5,
    0x5d,
    0xf0,
    0x6f,
    0x4c,
    0x52,
    0xc9,
    0xde,
    0x2b,
    0xcb,
    0xf6,
    0x95,
    0x58,
    0x17,
    0x18,
    0x39,
    0x95,
    0x49,
    0x7c,
    0xea,
    0x95,
    0x6a,
    0xe5,
    0x15,
    0xd2,
    0x26,
    0x18,
    0x98,
    0xfa,
    0x05,
    0x10,
    0x15,
    0x72,
    0x8e,
    0x5a,
    0x8a,
    0xac,
    0xaa,
    0x68,
    0xff,
    0xff,
    0xff,
    0xff,
    0xff,
    0xff,
    0xff,
    0xff,
  ]),
);
